package org.ilovecode.display {
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import gs.TweenLite;
	import gs.easing.*;
	import org.ilovecode.events.GalleryEvent;
	
	/**
	 * ...
	 * @author Vjekoslav Ratkajec
	 */
	public class ScrollableContainer extends MovieClip {
		
		private const SPACING:uint = 3;
		private const SCROLL_FACTOR:Number = 3;
		private const CONTENT_OFFSET:int = 20;
		private const SCROLL_SPEED:Number = 10;
		
		private var content:MovieClip;
		private var contentMask:MovieClip;
		private var positionMarker:Number = 0;
		
		private var _width:Number = -1;
		private var _height:Number = -1;
		private var _orientation:String = "vertical";
		
		public function ScrollableContainer(width:Number, height:Number, orientation:String = "vertical") {
			//Validate parameters
			if (width <= 0 || height <= 0 || (orientation != "horizontal" && orientation != "vertical")) {
				throw new VerifyError("Illegal parameters");
			}
			
			_width = width;
			_height = height;
			_orientation = orientation;
			
			configUI();
			initListeners();
		}
		
		private function configUI():void {
			content = new MovieClip();
			contentMask = new MovieClip();
			
			contentMask.graphics.beginFill(0);
			contentMask.graphics.drawRect(0, 0, _width, _height);
			contentMask.graphics.endFill();
			contentMask.mouseEnabled = false;
			
			this.addChild(content);
			this.addChild(contentMask);
			content.mask = contentMask;
		}
		
		private function initListeners():void {
			content.addEventListener(MouseEvent.MOUSE_OVER, content_MouseOver);
			content.addEventListener(MouseEvent.MOUSE_OUT, content_MouseOut);
			this.addEventListener(MouseEvent.MOUSE_WHEEL, this_MouseWheel);
		}
		
		//{ region Public
		
		public function setContent(items:Array):void {
			for each (var item:Sprite in items) {
				item.x = 0;
				item.y = (content.height == 0) ? 0 : (content.height + SPACING);
				item.buttonMode = true;
				doResize(item);
				item.addEventListener(MouseEvent.CLICK, item_Click);
				content.addChild(item);
			}
		}
		
		//} endregion
		
		//{ region Handlers
		
		private function content_MouseOver(event:MouseEvent):void {
			content.addEventListener(Event.ENTER_FRAME, content_EnterFrame);
		}
		
		private function content_MouseOut(event:MouseEvent):void {
			content.removeEventListener(Event.ENTER_FRAME, content_EnterFrame);
		}
		
		private function content_EnterFrame(event:Event):void {
			if (_orientation == "vertical") {
				//Check if scrolling up
				if ((this.mouseY < (this.contentMask.height * 1 / 8)) && (content.y + SCROLL_SPEED <= 0)) {
					content.y += SCROLL_SPEED;
				}
				
				//Check if scrolling down
				if ((this.mouseY > (this.contentMask.height * 7 / 8)) && 
						(content.y + content.height - SCROLL_SPEED > contentMask.height)) {
					content.y -= SCROLL_SPEED;
				}
				var scrollingArea:Number = content.height - contentMask.height;
				positionMarker = - (content.y / scrollingArea) * _height;
			} else {
				//Check if moving left
				if (this.mouseX < (this.contentMask.width * 1 / 8) && (content.x + SCROLL_SPEED <= 0)) {
					content.x += SCROLL_SPEED;
				}
				
				//Check if moving right
				if (this.mouseX > (this.contentMask.width * 7 / 8) && 
						(content.x + content.width + SCROLL_SPEED > contentMask.width)) {
					content.x -= SCROLL_SPEED;
				}
			}
		}
		
		private function this_MouseWheel(event:MouseEvent):void {
			var delta:int = event.delta;
			if (_orientation == "vertical") {
				var newY:Number = positionMarker - delta * (this.stage.frameRate / 2) * SCROLL_FACTOR;
				
				if (delta > 0) {
					if (newY > 0) {
						positionMarker = newY;
					} else {
						positionMarker = 0;
					}
				} 
				
				if (delta < 0) {
					if (newY < _height) {
						positionMarker = newY;
					} else {
						positionMarker = _height;
					}
				}
				
				scrollY();
			}
			
		}
		
		private function item_Click(event:MouseEvent):void {
			var thumbName:String = String(event.currentTarget.name).replace("_thumb", "");
			this.dispatchEvent(new GalleryEvent(GalleryEvent.ITEM_CLICK, thumbName));
		}
		
		//} endregion
		
		private function doResize(content:Sprite):void {
			var ratio:Number = 1;
			if (_orientation == "vertical") {
				if (content.width > this.width) {
					ratio = this.width / content.width;
					content.scaleX = ratio;
					content.scaleY = ratio;
				}
			} else {
				if (content.height > this.height) {
					ratio = this.height / content.height;
					content.scaleX = ratio;
					content.scaleY = ratio;
				}
			}
		}
		
		private function scrollY():void {
			var scrollingArea:Number = content.height - contentMask.height;
			var contentPosition:Number = - (positionMarker / _height) * scrollingArea;
			TweenLite.to(content, 0.2, { y:contentPosition, ease:Linear.easeOut } );
			trace(contentPosition);
		}
		
	}

}